iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0

LightGBM

GBDT(Gradient Boosting Decision Tree) 是利用弱分類器迭代訓練來得到最佳的模型,而 LightGBM(Light Gradient Boosting Machine)是實現 GBDT 的演算法。

由於 XGBoost 在訓練的時候空間暫存大,而 LightGBM 優化了 XGBoost 訓練的缺陷,在同樣的條件下加速 GBDT 演算法的運算。LightGBM 修補了 GBDT 在巨量資料下會遇到記憶體限制、速度上的限制,更適合於實際面的應用。

Leaf-wise的優點是在分裂次數相同的情況下,可以降低更多的誤差以達到更好的準確度;但是葉子可能因此一直長下去導致過度擬合,這裡可以增加 max_depth 的數量限制防止過擬合。

LightGBM 特色

參考來源

  • 速度更快
    • 採用直方圖演算法將遍歷樣本轉變為遍歷直方圖,極大的降低了時間複雜度。
    • 訓練過程中採用單邊梯度演算法過濾掉梯度小的樣本,減少了大量的計算。
    • 採用了基於 Leaf-wise 演算法的增長策略構建樹,減少了很多不必要的計算量。
    • 採用優化後的特徵並行、資料並行方法加速計算,當資料量非常大的時候還可以採用投票並行的策略。
    • 對快取也進行了優化,增加了快取命中率。
  • 記憶體消耗更小
    • 採用直方圖演算法將儲存特徵值轉變為儲存 bin 值,降低了記憶體消耗。
    • 訓練過程中採用互斥特徵捆綁演算法減少了特徵數量,降低了記憶體消耗。

安裝方式

pip install lightgbm

實作程式碼

import lightgbm as lgb
from lightgbm import LGBMClassifier

classifier = lgb.LGBMClassifier(objective = 'binary', 
                                learning_rate = 0.05, 
                                n_estimators = 100, 
                                random_state=0)
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)

print(cm)
>>> [[59  8]
     [ 4 29]]
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred))

看圖說故事

faeture importance

LGBM_grid_measure = measure_performance(X = X_test, y = y_test, clf = classifier, show_classification_report=True, show_confusion_matrix=True)

# feature importances
print('Feature importances:', list(classifier.feature_importances_))

# visualization
print('Plot feature importances...')
ax = lgb.plot_importance(classifier, max_num_features=len(train))
plt.show()

樹狀圖

ax = lgb.plot_tree(classifier, figsize=(20, 8), show_info=['split_gain'])
plt.show()

比較目前所學的演算法

我們發現基本上有 ensemble 的演算法準確度都相當地高,另外這份資料集剛好對 KNN 也有不錯的分類效果。

GridSearch

在機器學習中,本身的資料源和特徵資料處理其實是界定模型的準度上限(upper bound),不同的演算法只是去逼近這個上限。我們測試不同的演算法同時,我們可以進行不同參數的評估與計算準確率來逼近上限。

以下用 LightGBM 來示範 GridSearch(網格搜索法),可以輸入自己想要的參數組合,藉此找到最優的參數。

實作程式碼

# 建立參數
param_grid = {
    'num_leaves': [30, 40], 
    'feature_fraction': [0.2, 0.3],
    'bagging_fraction': [0.6, 0.7],
    'max_depth':[3, 5, 7],
    'max_bin':[20],
    'lambda_l1':[0.3, 0.6],
    'lambda_l2':[0.08, 0.09],
    'min_split_gain':[0.04, 0.05],
    'min_child_weight':[7]
}

# 建立 LightGBM模型
classifier = lgb.LGBMClassifier(objective = 'binary', 
                                learning_rate = 0.05, 
                                n_estimators = 100, 
                                random_state=0)
# GridSearchCV
from sklearn.model_selection import GridSearchCV
gridsearch = GridSearchCV(classifier, param_grid)

# Final Model
print('Start predicting...')
LGBM = lgb.LGBMClassifier(objective = 'binary',
                         learning_rate = 0.05, 
                         n_estimators = 100, 
                         random_state=0,
                         num_leaves = gridsearch.best_params_['num_leaves'],
                         feature_fraction = gridsearch.best_params_['feature_fraction'], 
                         bagging_fraction = gridsearch.best_params_['bagging_fraction'],
                         max_depth = gridsearch.best_params_['max_depth'],
                         max_bin = gridsearch.best_params_['max_bin'],
                         lambda_l1 = gridsearch.best_params_['lambda_l1'],
                         lambda_l2 = gridsearch.best_params_['lambda_l2'],
                         min_split_gain = gridsearch.best_params_['min_split_gain'],
                         min_child_weight = gridsearch.best_params_['min_child_weight'])
%time LGBM_fit = LGBM.fit(X_train, y_train)
print('Predicting is over')

github 程式碼

更詳細可以請參考


上一篇
Day 25 : XGBoost
下一篇
Day 27 : 模型解釋 Shap
系列文
Python資料分析學習地圖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言